package org.apache.commons.logging;

import java.util.HashMap;
import java.util.logging.Level;
import java.util.logging.Logger;

public class LogFactory {
	private static HashMap<String, Log> logMap = new HashMap<String, Log>();

	public static synchronized Log getLog(String name) {
		Log log = logMap.get(name);
		if (log != null) {
			return log;
		}
		final Logger _logger = java.util.logging.Logger.getLogger(name);
		log = new Log() {
			private StackTraceElement getStackTraceElement() {
				return new Throwable().getStackTrace()[3];
			}

			private void log(Level l, Object o) {
				StackTraceElement ste = getStackTraceElement();
				_logger.logp(l, ste.getClassName(), ste.getMethodName(), "" + o);
			}

			private void log(Level l, Object o, Throwable t) {
				StackTraceElement ste = getStackTraceElement();
				_logger.logp(l, ste.getClassName(), ste.getMethodName(), "" + o, t);
			}

			@Override
			public boolean isTraceEnabled() {
				return _logger.isLoggable(Level.FINE);
			}

			@Override
			public boolean isDebugEnabled() {
				return _logger.isLoggable(Level.CONFIG);
			}

			@Override
			public boolean isInfoEnabled() {
				return _logger.isLoggable(Level.INFO);
			}

			@Override
			public boolean isWarnEnabled() {
				return _logger.isLoggable(Level.WARNING);
			}

			@Override
			public boolean isErrorEnabled() {
				return _logger.isLoggable(Level.SEVERE);
			}

			@Override
			public boolean isFatalEnabled() {
				return _logger.isLoggable(Level.SEVERE);
			}

			@Override
			public void trace(Object o) {
				log(Level.FINE, o);
			}

			@Override
			public void trace(Object o, Throwable t) {
				log(Level.FINE, o, t);
			}

			@Override
			public void debug(Object o) {
				log(Level.CONFIG, o);
			}

			@Override
			public void debug(Object o, Throwable t) {
				log(Level.CONFIG, o, t);
			}

			@Override
			public void info(Object o) {
				log(Level.INFO, o);
			}

			@Override
			public void info(Object o, Throwable t) {
				log(Level.INFO, o, t);
			}

			@Override
			public void warn(Object o) {
				log(Level.WARNING, o);
			}

			@Override
			public void warn(Object o, Throwable t) {
				log(Level.WARNING, o, t);
			}

			@Override
			public void error(Object o) {
				log(Level.SEVERE, o);
			}

			@Override
			public void error(Object o, Throwable t) {
				log(Level.SEVERE, o, t);
			}

			@Override
			public void fatal(Object o) {
				log(Level.SEVERE, o);
			}

			@Override
			public void fatal(Object o, Throwable t) {
				log(Level.SEVERE, o, t);
			}
		};
		logMap.put(name, log);
		return log;
	}

	public static Log getLog(Class<?> clazz) {
		return getLog(clazz.getClassLoader().toString());
	}
}